#include "../inc/list.h"
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>




P_Node_t InitNewNode( dataType * NewData )
{

	// 申请空间
	P_Node_t newNode = calloc(1, sizeof(Node_t));
	if (newNode == NULL)
	{
		printf("Calloc NewNode error");
		return NULL ;
	}
	

	// 初始化数据域
	if (NewData != NULL)
	{
		newNode->Data = *NewData ;
	}

	// 初始化指针域
	newNode->Next = newNode->Prev = newNode ;

	// 返回节点地址
	return newNode ;
}

void Add2ListHead( P_Node_t head ,  P_Node_t newNode )
{

	/////////////////先操作新节点再操作链表////////////////
	/////////////////////防止链表断裂////////////////////
	// 1 让新节点的后继指针先指向第一个有效数据
	newNode->Next = head->Next ;

	// 2. 让新节点的前驱指针，先指向头节点
	newNode->Prev = head ;

	// 3. 让链表的头节点的后继指向新节点
	head->Next = newNode ;

	// 4. 让链表的第一个有效节点的前驱指向新节点
	newNode->Next->Prev = newNode ;

	return ;
}

void Add2ListTail( P_Node_t head , P_Node_t newNode )
{
	newNode->Next = head ;
	newNode->Prev = head->Prev ;

	head->Prev = newNode ;
	newNode->Prev->Next = newNode ;

}

void Add2List( P_Node_t Prev , P_Node_t New  , P_Node_t Next )
{
	Prev->Next = New ;
	New->Next = Next ;

	Next->Prev = New ;
	New->Prev = Prev ;
}


void displayList( P_Node_t head , void (* Printer)(dataType *)  )
{

	// tmp 初始化指向链表的第一个有效数据
	for (P_Node_t tmp = head->Next ; tmp != head ; tmp = tmp->Next )
	{
		Printer(&tmp->Data);
		// printf("Num:%d\t" , tmp->Data) ;
	}
	printf("\n");

}


P_Node_t findNode( P_Node_t head , dataType data  , 
		bool (*Comparator)(dataType * , dataType *) )
{
	P_Node_t tmp = NULL ;
	for ( tmp = head->Next ; tmp != head ; tmp = tmp->Next )
	{
		if (Comparator( &tmp->Data , &data ))
		{
			return tmp ;
		}
	}
	
	return NULL ;
}


void del4List( P_Node_t del )
{

	del->Prev->Next = del->Next ;

	del->Next->Prev = del->Prev ;

	del->Next = del->Prev = del;

}

void delData4List( P_Node_t Prev , P_Node_t del ,  P_Node_t Next )
{

	Prev->Next = Next ;
	Next->Prev = Prev ;

	del->Next = del->Prev = del ;
}


void Destruction( P_Node_t head  , P_Node_t tmp )
{

	if (head == tmp)
	{
		free(head);
		return ;
	}
	
	// 递归，注意参数需要把问题的规模缩小
	Destruction( head , tmp->Next );
	
	free(tmp);

	return ;
}

